

package com.maoshi.shop.mp.comment.api.controller;

import com.alibaba.fastjson.JSON;
import com.maoshi.shop.bean.model.User;
import com.maoshi.shop.distribution.comment.model.DistributionUserBind;
import com.maoshi.shop.distribution.comment.service.DistributionUserBindService;
import com.maoshi.shop.mp.comment.api.util.UserInfo;
import com.maoshi.shop.mp.comment.component.WxMaInRedisConfig;
import com.maoshi.shop.mp.comment.uril.HttpGetUtil;
import com.maoshi.shop.security.comment.model.AppConnect;
import com.maoshi.shop.security.comment.service.AppConnectService;
import com.maoshi.shop.service.UserService;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 */
@RestController
@RequestMapping("/wx/portal")
public class WxPortalController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private WxMpMessageRouter wxMpMessageRouter;

    //合并代码开始
    @Autowired
    private DistributionUserBindService distributionUserBindService;

    @Autowired
    private AppConnectService appConnectService;

    @Autowired
    WxMaInRedisConfig wxMaInRedisConfig;

    @Autowired
    UserService userService;
    //合并代码结束

    private static final String ENC_TYPE_AES = "aes";

    /**
     * 用来进行微信认证，也就是当在：
     * 公众号官方管理后台->开发->基本配置->修改配置 时，需要进行的校验
     *
     * @return
     */
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {

        this.logger.info("\n接收到来自微信服务器的认证消息：[{}, {}, {}, {}]", signature,
                timestamp, nonce, echostr);
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法，请核实!");
        }

        if (wxMpService.checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }

        return "非法请求";
    }

    /**
     * 接收公众号的消息
     *
     * @return
     */
    @PostMapping(produces = "application/xml; charset=UTF-8")
    public String post(@RequestBody String requestBody,
                       @RequestParam("signature") String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce,
                       @RequestParam("openid") String openid,
                       @RequestParam(name = "encrypt_type", required = false) String encType,
                       @RequestParam(name = "msg_signature", required = false) String msgSignature) {
        this.logger.info("\n接收微信请求：[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                openid, signature, encType, msgSignature, timestamp, nonce, requestBody);


        String out = null;
        if (encType == null) {
            // 明文传输的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);

            //合并代码开始
            if(inMessage!=null){
                if (inMessage.getMsgType().equals("event")) {
                    //获取用户信息
                    String unionId = "";
                    String nickname = "";
                    String picUrl = "";
                    String sex = "";
                    Map<String, String> rel = UserInfo.getUnionId(openid);
                    String subscribe = rel.get("subscribe");
                    if(subscribe.equals("1")){
                        unionId = rel.get("unionid");
                        nickname = rel.get("nickname");
                        picUrl = rel.get("headimgurl");
                        sex = rel.get("sex");
                    }
                    System.out.println(unionId);

                    //获取event类型
                    String event =inMessage.getEvent();
                    //获取二维码参数
                    String eventKey=inMessage.getEventKey();
                    System.out.println("二维码参数"+eventKey);
                    //分割二维码字符串参数值type@shopId@distributionUserId@orderTypeBasket@shopType
                    String[] eventKeys = eventKey.split("@");
                    String type= null;
                    Long shopId= null;
                    Long distributionUserId= null;
                    Integer orderTypeBasket= null;
                    Integer shopType=null;
                    try {
                        type = eventKeys[1];
                        shopId = Long.parseLong(eventKeys[2]);
                        distributionUserId = Long.parseLong(eventKeys[3]);
                        orderTypeBasket = Integer.parseInt(eventKeys[4]);
                        shopType=Integer.parseInt(eventKeys[5]);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    //根据unionId查询AppConnect
                    AppConnect appConnect = appConnectService.getByUnionId(unionId);

                    //用户未关注时，进行关注后的事件推送
                    if (event.equals("subscribe")) {
                        //根据用户信息  读取对应关系
                        //若appConnect存在,则启用原先的对应关系
                        if(appConnect!=null){
                            userService.updateStatusByUserId(appConnect.getUserId(),1);
                            //根据userId查询对应关系表
                            DistributionUserBind distributionUserBind = distributionUserBindService.getByUserId(appConnect.getUserId());
                            //若存在对应关系，则修改该条数据状态为生效
                            if(distributionUserBind!=null){
                                //根据userId改变关系表里该条数据状态为生效(state=1)
                                distributionUserBindService.updateStateByUserId(appConnect.getUserId(),1);
                            }
                        }else {
                            //若没有，写入tz_app_connect表
                            AppConnect appConnectNew=new AppConnect();

                            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                            appConnectNew.setUserId(uuid);
                            appConnectNew.setBizUserId(openid);
                            System.out.println("setopenid"+openid);
                            appConnectNew.setBizUnionid(unionId);
                            appConnectNew.setAppId(2);
                            appConnectNew.setNickName(nickname);
                            appConnectService.insert(appConnectNew);

                            //写入tz_user表
                            User user=new User();
                            user.setUserId(appConnectNew.getUserId());
                            user.setNickName(nickname);
                            user.setModifyTime(new Date());
                            user.setUserRegtime(new Date());
                            if(sex.equals("2")){
                                user.setSex("F");
                            }else {
                                user.setSex("M");
                            }
                            user.setPic(picUrl);
                            user.setStatus(1);
                            userService.insert(user);

                            //同时写入对应关系
                            DistributionUserBind distributionUserBindNew = new DistributionUserBind();
                            distributionUserBindNew.setUserId(appConnectNew.getUserId());
                            distributionUserBindNew.setShopId(shopId);
                            distributionUserBindNew.setDistributionUserId(distributionUserId);
                            distributionUserBindNew.setUpdateTime(new Date());
                            distributionUserBindNew.setBindTime(new Date());
                            distributionUserBindNew.setState(1);
                            distributionUserBindService.insert(distributionUserBindNew);
                        }
                        //并推送消息
                        System.out.println("推送店铺消息byShopId"+shopId);
                        miniAppPush(inMessage,type,orderTypeBasket,shopType,shopId);

                    }else if (event.equals("unsubscribe")){
                        //根据userId改变用户表里该条数据状态为失效(status=0)
                        AppConnect appConnect1 = appConnectService.getByOpenId(openid);
                        System.out.println(appConnect1.getUserId());
                        userService.updateStatusByUserId(appConnect1.getUserId(),0);
                        System.out.println("用户状态修改成功");
                        //根据userId改变关系表里该条数据状态为失效(state=-1)
                        distributionUserBindService.updateStateByUserId(appConnect1.getUserId(),-1);
                        System.out.println("解绑成功");
                    }else if(event.equals("SCAN")){
                        //用户已关注时的事件推送
                        System.out.println("推送店铺消息byShopId"+shopId);
                        miniAppPush(inMessage,type,orderTypeBasket,shopType,shopId);
                    }
                }
            }
            //合并代码结束

            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null) {
                return "";
            }

            out = outMessage.toXml();
        } else if (ENC_TYPE_AES.equalsIgnoreCase(encType)) {
            // aes加密的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxMpService.getWxMpConfigStorage(),
                    timestamp, nonce, msgSignature);
            this.logger.debug("\n消息解密后内容为：\n{} ", inMessage.toString());
            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null) {
                return "";
            }

            out = outMessage.toEncryptedXml(wxMpService.getWxMpConfigStorage());
        }

        this.logger.debug("\n组装回复信息：{}", out);
        return out;
    }

    private WxMpXmlOutMessage route(WxMpXmlMessage message) {
        try {
            return wxMpMessageRouter.route(message);
        } catch (Exception e) {
            this.logger.error("路由消息时出现异常！", e);
        }
        return null;
    }

    //合并代码开始
    private void miniAppPush(WxMpXmlMessage inMessage,String type,Integer orderTypeBasket,Integer shopType,Long shopId){

        String accessToken= UserInfo.getToken();
        String PUSH_APPLET_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;

        System.out.println("*************推送小程序开始*************");
        Map<String, Object> params = new HashMap<>();
        params.put("touser", inMessage.getFromUser());
        params.put("msgtype", "miniprogrampage");
        Map<String, Object> miniprogrampageMap = new HashMap<>();
        miniprogrampageMap.put("title", "小程序");
        miniprogrampageMap.put("appid", "wx394fc0ec5ad25592");
        if(type.equals("hotel")){
            miniprogrampageMap.put("pagepath", "pages/orderInRoom/orderInRoom?orderTypeBasket="+orderTypeBasket);
            miniprogrampageMap.put("thumb_media_id", "YOXgSeJde8uRVEHo1svj-zshvYgU4-JIkCO-0Jl5xpE");
        }else if(type.equals("drainage")){
            //如果是店铺的引流二维码，则推送的小程序卡片直接跳转到该店铺的首页
            if(shopType==2){
                miniprogrampageMap.put("pagepath", "pages/shopPage/shopPage?shopId="+shopId);
            }else {
                miniprogrampageMap.put("pagepath", "pages/index/index");
            }
            miniprogrampageMap.put("thumb_media_id", "YOXgSeJde8uRVEHo1svj-zshvYgU4-JIkCO-0Jl5xpE");
        }else if(type.equals("machine")){
            miniprogrampageMap.put("pagepath", "pages/index/index");
            miniprogrampageMap.put("thumb_media_id", "YOXgSeJde8uRVEHo1svj-zshvYgU4-JIkCO-0Jl5xpE");
        }
        //miniprogrampageMap.put("thumb_media_id", "YOXgSeJde8uRVEHo1svj-4mVELUDedMlT3rGYnrSad4");
        params.put("miniprogrampage", miniprogrampageMap);
        String result = HttpGetUtil.doPostJson(PUSH_APPLET_URL, JSON.toJSONString(params));
        System.out.println(result);
        System.out.println("*************推送小程序结束result:" + result);
    }
    //合并代码结束

}
